package com.seh.contentcenter.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.seh.contentcenter.controller.AddressInfoController;
import com.seh.contentcenter.controller.GoodsController;
import com.seh.contentcenter.domain.WrapperResult;
import com.seh.contentcenter.dto.AddressInfoDTO;
import com.seh.contentcenter.dto.DeliverDTO;
import com.seh.contentcenter.dto.GoodsDTO;
import com.seh.contentcenter.dto.UserDTO;
import com.seh.contentcenter.entity.Deliver;
import com.seh.contentcenter.feignclient.UserCenterFeignClient;
import com.seh.contentcenter.mapper.DeliverMapper;
import com.seh.contentcenter.service.DeliverService;
import com.seh.contentcenter.utils.DTOUtil;
import com.seh.contentcenter.utils.UserUtil;
import com.seh.contentcenter.utils.WrapperUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.*;

@Service
public class DeliverServiceImpl implements DeliverService {
    @Autowired
    private DeliverMapper deliverMapper;

    @Autowired
    private RedisTemplate<String, Object> objectRedisTemplate;

    @Autowired
    private UserCenterFeignClient userCenterFeignClient;

    @Autowired
    private GoodsController goodsController;

    private static Integer pageSize = 4;//分页查询，每页分的数量


    /**
     * 查询所有外送订单信息
     *
     * @return
     */
    @Override
    public List<DeliverDTO> findAllDeliverInfo(Integer pageIndex) {
        Page<Deliver> page = new Page<>(pageIndex, pageSize);

        page = deliverMapper.selectPage(page, WrapperUtil.pageWrapper(0, "create_time", "deliver_status"));
        List<Deliver> deliverList = page.getRecords();
        List<DeliverDTO> deliverDTOList = new ArrayList<>();
        deliverList.forEach(f -> {
            DeliverDTO deliverDTO = DTOUtil.convertDeliver(f);
            //添加用户信息
            UserDTO userInfoById = userCenterFeignClient.findUserInfoById(f.getIssuerId());
            deliverDTO.setUserDTO(userInfoById);

            deliverDTOList.add(deliverDTO);
        });
        return deliverDTOList;
    }

    /**
     * 通过外送订单编号，查看外送订单的详细信息
     *
     * @param deliverId
     * @return
     */
    @Override
    public DeliverDTO selectOneById(Integer deliverId) {
        Deliver deliver = deliverMapper.selectById(deliverId);
        UserDTO userInfoById = userCenterFeignClient.findUserInfoById(deliver.getUserId());
        GoodsDTO goodsDTO = goodsController.findById(deliver.getGoodsId()).getData();
        DeliverDTO deliverDTO = DTOUtil.convertDeliver(deliver);
        deliverDTO.setUserDTO(userInfoById);
        return deliverDTO;
    }

    /**
     * 发布新的代取任务
     *
     * @param deliver
     * @return
     */
    @Override
    public String addNewDeliver(Deliver deliver) {
        int insert = deliverMapper.insert(deliver);
        if (insert == 1) {
            return "添加成功";
        }
        return "添加失败";
    }

    /**
     * 通过快递主键，逻辑删除
     *
     * @param deliverId
     * @return
     */
    @Override
    public String deleteDeliver(Integer deliverId) {
        int i = deliverMapper.deleteById(deliverId);
        if (i == 1) {
            return "删除成功";
        }
        return "删除失败";
    }

    /**
     * 查看用户所有发布的跑腿信息
     *
     * @param issuerId
     * @return
     */
    @Override
    public List<DeliverDTO> findAllDeliverByUserId(Integer issuerId, Integer pageIndex) {
        Page<Deliver> page = new Page<>(pageIndex, pageSize);
        QueryWrapper<Deliver> queryWrapper = WrapperUtil.pageWrapper(issuerId, "create_time", "issuer_id");
        page = deliverMapper.selectPage(page, queryWrapper);
        List<Deliver> deliverList = page.getRecords();
        List<DeliverDTO> deliverDTOList = new ArrayList<>();
        deliverList.forEach(f -> {
            DeliverDTO deliverDTO = DTOUtil.convertDeliver(f);
            deliverDTOList.add(deliverDTO);
        });
        return deliverDTOList;
    }

    /**
     * 根据宿舍园区和快递地址查询订单
     *
     * @param addressName
     * @param receiveName
     * @param price       按照价格排序
     * @param publishTime 按照时间排序
     * @return
     */
    @Override
    public List<DeliverDTO> findAllDeliverByAddress(String addressName, String receiveName,
                                                    String price, String publishTime, Integer pageIndex) {
        Page<Deliver> page = new Page<>(pageIndex, pageSize);
        QueryWrapper<Deliver> queryWrapper = new QueryWrapper<>();
        switch (price) {
            case "最高":
                queryWrapper.orderByDesc("deliver_price");
                break;
            case "最低":
                queryWrapper.orderByAsc("deliver_price");
                break;
            default:
                // 不做处理或者抛出异常，根据实际需求决定
                break;
        }

        switch (publishTime) {
            case "最新":
                queryWrapper.orderByDesc("create_time");
                break;
            case "最早":
                queryWrapper.orderByAsc("create_time");
                break;
            default:
                // 不做处理或者抛出异常，根据实际需求决定
                break;
        }

        if (!addressName.equals("不限地点")) {
            queryWrapper.like("address_name", addressName);
        }
        if (!receiveName.equals("不限园区")) {
            queryWrapper.like("receive_name", receiveName);
        }
        queryWrapper.eq("deliver_status", 0).orderByDesc("create_time");

        Page<Deliver> deliverPage = deliverMapper.selectPage(page, queryWrapper);
        List<Deliver> delivers = deliverPage.getRecords();

        List<DeliverDTO> deliverDTOList = new ArrayList<>();
        delivers.forEach(f -> {
            DeliverDTO deliverDTO = DTOUtil.convertDeliver(f);
            UserDTO userInfoById = userCenterFeignClient.findUserInfoById(f.getIssuerId());
            deliverDTO.setUserDTO(userInfoById);

            deliverDTOList.add(deliverDTO);
        });
        return deliverDTOList;
    }

    /**
     * 查看某一用户的代取信息
     * @param userId
     * @param pageIndex
     * @return
     */
    @Override
    public List<DeliverDTO> findAllDeliverUserDo(Integer userId, Integer pageIndex) {
        Page<Deliver> page = new Page<>(pageIndex, pageSize);
        QueryWrapper<Deliver> queryWrapper =
                WrapperUtil.pageStatusWrapper(userId,"create_time", "user_id", "deliver_status");
        page = deliverMapper.selectPage(page, queryWrapper);
        List<Deliver> deliverList = page.getRecords();
        List<DeliverDTO> deliverDTOList = new ArrayList<>();
        deliverList.forEach(f -> {
            DeliverDTO deliverDTO = DTOUtil.convertDeliver(f);
            UserDTO userDTO = UserUtil.getUserDTOFromCache(f.getUserId(), objectRedisTemplate, userCenterFeignClient);
            UserDTO issuerDTO = UserUtil.getUserDTOFromCache(f.getIssuerId(), objectRedisTemplate, userCenterFeignClient);
            deliverDTO.setUserDTO(userDTO);
            deliverDTO.setIssuerDTO(issuerDTO);
            deliverDTOList.add(deliverDTO);
        });
        return deliverDTOList;
    }

    /**
     * 查看某一用户被代取的信息
     * @param issuerId
     * @param pageIndex
     * @return
     */
    @Override
    public List<DeliverDTO> findAllDeliverUserBy(Integer issuerId, Integer pageIndex) {
        Page<Deliver> page = new Page<>(pageIndex, pageSize);
        QueryWrapper<Deliver> queryWrapper =
                WrapperUtil.pageStatusWrapper(issuerId,"create_time", "issuer_id", "deliver_status");
        page = deliverMapper.selectPage(page, queryWrapper);
        List<Deliver> deliverList = page.getRecords();
        List<DeliverDTO> deliverDTOList = new ArrayList<>();
        deliverList.forEach(f -> {
            DeliverDTO deliverDTO = DTOUtil.convertDeliver(f);
            UserDTO userDTO = UserUtil.getUserDTOFromCache(f.getUserId(), objectRedisTemplate, userCenterFeignClient);
            deliverDTO.setUserDTO(userDTO);
            UserDTO issuerDTO = UserUtil.getUserDTOFromCache(f.getIssuerId(), objectRedisTemplate, userCenterFeignClient);
            deliverDTO.setIssuerDTO(issuerDTO);
            deliverDTOList.add(deliverDTO);
        });
        return deliverDTOList;
    }

    /**
     * 用户代取某一跑腿，修改此跑腿的状态
     * @param userId
     * @return
     */
    @Override
    public String updateDeliver(Integer deliverId, Integer userId) {
        String lockKey = "addDeliverLock";
        String lockValue = UUID.randomUUID().toString();
        Integer deliverStatus = deliverMapper.selectById(deliverId).getDeliverStatus();
        try {
            Boolean lockAcquired = objectRedisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, Duration.ofSeconds(10));
            if (lockAcquired != null && lockAcquired && deliverStatus == 0) {
                //获取锁成功，执行业务逻辑
                Deliver deliver = new Deliver();
                deliver.setDeliverId(deliverId);
                deliver.setUserId(userId);
                deliver.setDeliverStatus(1);
                int update = deliverMapper.updateById(deliver);
                if (update == 1) {
                    return "代取成功";
                } else {
                    return "代取失败";
                }
            }else {
                // 获取锁失败，另一个进程已在操作
                return "添加失败，请稍后再试";
            }
        } finally {
            // 释放锁
            String currentLockValue = String.valueOf(objectRedisTemplate.opsForValue().get(lockKey));
            if (currentLockValue != null && currentLockValue.equals(lockValue)) {
                objectRedisTemplate.delete(lockKey);
            }
        }
    }

    /**
     * 确认跑腿完成
     * @param deliverId
     * @return
     */
    @Override
    public String updateDeliverDone(Integer deliverId) {
        Deliver deliver = new Deliver();
        deliver.setDeliverId(deliverId);
        deliver.setDeliverStatus(2);
        int update = deliverMapper.updateById(deliver);
        if (update == 1) {
            return "更新成功";
        }
        return "更新失败";
    }

}
